#ifndef __SOCKETCLIENT__
#define __SOCKETCLIENT__



#include "SocketBuf.h"
#include "SocketStruct.h"
#include "SocketMacros.h"
#include "SocketGlobals.h"
#include "SocketBase.h"
#include "SocketCompat.h"

// Uncomment the next line to allow sctest1
// and sctest2 to compile and run.
//#define SC_TEST_DEBUG

class SocketClient : public SocketBase
{
private:
  unsigned short port;
  struct timeval read_timeout;
  float read_timeout_float;
  struct timeval write_timeout;
  float write_timeout_float;
  int use_multicast;
  int suppress_multicast_loop;
  void *multicast_address;  /* was struct ip_mreq and conditionally defined.
			       caused enough problems to make this a void *
			       and allocate it off the heap if 
			       SM_HAVE_MULTICAST is defined. */
  struct sockaddr_in multicast_group_address;


  friend class Tunnel;

  int connectAsTunnel(char *remote_host_name);

#ifndef SC_TEST_DEBUG
  SocketStruct *current_socket;
#endif

  int				allowMulticastLoopback();
  int				suppressMulticastLoopback();

public:
  SocketClient (unsigned short target_port,
		int read_timeout_secs = 1,
		int read_timeout_usecs = 0,
		int write_timeout_secs = 1,
		int write_timeout_usecs = 0,
		int user_quiet = 0,
		int user_sys_v_signals = 0,
		int user_use_multicast = 0,
		int user_suppress_multicast_loopback = 1,
		char *initial_server_name = 0);
  ~SocketClient();

  int				connectToServer(const char *server_name,
						char *interface_name = NULL);
  int				closeConnection();

  SocketBuf* 			readWithPollAndTimeout();
  SocketBuf* 			readWithTimeout();
  SocketBuf* 			recoverFromReadError();
  int				writeWithTimeout(SocketBuf *sbuf);

  int				getLastMessage();

  int				serverUsingUDP();

  int 				getUsingMulticast();
  int				setUsingMulticast(int on_or_off);

  int				getSuppressingMulticastLoopback();
  int				setSuppressingMulticastLoopback(int on_or_off);

  unsigned short		getPort();
  int				setPort(unsigned short new_port);

  void				setFDSet(fd_set *fds);
  int				readyToRead(fd_set *fds);

  int				selectOnSocket();

#ifdef SC_TEST_DEBUG
  SocketStruct *current_socket;
#endif  
};

#endif
